package com.huilian.iotbox.data.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.huilian.iotbox.data.common.RedisKey;
import com.huilian.iotbox.data.controller.ControllerException;
import com.huilian.iotbox.data.enums.BaiduImageStatusEnum;
import com.huilian.iotbox.data.service.BaiduApiService;
import org.springframework.core.io.UrlResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author 曹畅
 * @version 1.0
 * @date 2020/8/5 16:18
 */
@Service
public class BaiduApiServiceImpl implements BaiduApiService {
    @Resource
    private RedisTemplate<String, Serializable> redisCacheTemplate;

    /**
     * 获取权限token
     *
     * @return 返回示例：
     * {
     * "access_token": "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567",
     * "expires_in": 2592000
     * }
     */
    public String getAuth() {
        String baiduToken = (String) redisCacheTemplate.opsForValue().get(RedisKey.BAIDU_TOKEN);
        if (baiduToken == null) {
            // 官网获取的 API Key 更新为你注册的
            String clientId = "5ccR4eA6yNvyzc1eTpaUVyyj";
            // 官网获取的 Secret Key 更新为你注册的
            String clientSecret = "kZzZSLrwdG6GySFDrObLWj3DlABMXFMU";
            return getAuth(clientId, clientSecret);
        } else {
            return baiduToken;
        }
    }


//    public static RedisTemplate getRedisTemplate(JedisConnectionFactory connectionFactory){
//
//        RedisTemplate redisCacheTemplate = new RedisTemplate();
//        redisCacheTemplate.setConnectionFactory(connectionFactory);
//        StringRedisSerializer serializer = new StringRedisSerializer();
//        redisCacheTemplate.setDefaultSerializer(serializer);
//        redisCacheTemplate.setKeySerializer(serializer);
//        redisCacheTemplate.setValueSerializer(serializer);
//
//        /**必须执行这个函数,初始化RedisTemplate*/
//        redisCacheTemplate.afterPropertiesSet();
//        return redisCacheTemplate;
//    }

    /**
     * 获取API访问token
     * 该token有一定的有效期，需要自行管理，当失效时需重新获取.
     *
     * @param ak - 百度云官网获取的 API Key
     * @param sk - 百度云官网获取的 Securet Key
     * @return assess_token 示例：
     * "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"
     */
    public String getAuth(String ak, String sk) {


        // 获取token地址
        String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
        String getAccessTokenUrl = authHost
                // 1. grant_type为固定参数
                + "grant_type=client_credentials"
                // 2. 官网获取的 API Key
                + "&client_id=" + ak
                // 3. 官网获取的 Secret Key
                + "&client_secret=" + sk;
        try {
            URL realUrl = new URL(getAccessTokenUrl);
            // 打开和URL之间的连接
            HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.err.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String result = "";
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            /**
             * 返回结果示例
             */
            System.err.println("result:" + result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            String access_token = jsonObject.getString("access_token");
            String expires_in = jsonObject.getString("expires_in");

            Integer validityDay = Integer.parseInt(expires_in) / (60 * 60 * 24);
            redisCacheTemplate.opsForValue().set(RedisKey.BAIDU_TOKEN, access_token, validityDay, TimeUnit.DAYS);
            return access_token;
        } catch (Exception e) {
            System.err.printf("获取token失败！");
            e.printStackTrace(System.err);
        }
        return null;
    }


    /**
     * 将本地图片进行Base64位编码
     *
     * @param
     * @return
     */
    public String encodeImgageToBase64(File imageFile) {
        // 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
        // 其进行Base64编码处理
        byte[] data = null;
        // 读取图片字节数组
        try {
            InputStream in = new FileInputStream(imageFile);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);// 返回Base64编码过的字节数组字符串
    }

    public String request(String httpUrl, String httpArg) {
        BufferedReader reader = null;
        String result = null;
        StringBuffer sbf = new StringBuffer();
        try {
            // 用java JDK自带的URL去请求
            URL url = new URL(httpUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            // 设置该请求的消息头
            // 设置HTTP方法：POST
            connection.setRequestMethod("POST");
            // 设置其Header的Content-Type参数为application/x-www-form-urlencoded
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            // 填入apikey到HTTP header
            connection.setRequestProperty("apikey", "5ccR4eA6yNvyzc1eTpaUVyyj");
            // 将第二步获取到的token填入到HTTP header
            connection.setRequestProperty("access_token", getAuth());
            connection.setDoOutput(true);
            connection.getOutputStream().write(httpArg.getBytes("UTF-8"));
            connection.connect();
            InputStream is = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String strRead = null;
            while ((strRead = reader.readLine()) != null) {
                sbf.append(strRead);
                sbf.append("\r\n");
            }
            reader.close();
            result = sbf.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /***获取身份证的有效期  type 1 身份证正面 type 2 身份证反面*/
    @Override
    public JSONObject getIdentityPeriod(String imgName, String imgUrl, Integer type) throws IOException {
        JSONObject jsonObject = new JSONObject();
        //获取图片文件
        String imageBase = encodeImgageToBase64(getImgFile(imgName, imgUrl));
        imageBase = imageBase.replaceAll("\r\n", "");
        imageBase = imageBase.replaceAll("\\+", "%2B");
        String httpUrl = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + getAuth();
        String httpArg;
        //	front：身份证含照片的一面；back：身份证带国徽的一面
        httpArg = "detect_direction=true&id_card_side=back&image=" + imageBase;
        if (type == 1) {
            httpArg = "detect_direction=true&id_card_side=front&image=" + imageBase;
        }
        String jsonResult = request(httpUrl, httpArg);
        System.out.println("返回的结果--------->" + jsonResult);
        JSONObject json = JSONObject.parseObject(jsonResult);
        JSONObject words_result = (JSONObject) json.get("words_result");

        String status = json.getString("image_status");
        String msg = "";
        if (BaiduImageStatusEnum.NORMAL.getCode().equals(status)) {
            if (type == 1) {
                JSONObject name = words_result.getJSONObject("姓名");
                JSONObject certNo = words_result.getJSONObject("公民身份号码");
                jsonObject.put("name", ObjectUtils.isEmpty(name) ? name : name.getString("words"));
                jsonObject.put("certNo", ObjectUtils.isEmpty(certNo) ? certNo : certNo.getString("words"));
            } else {
                JSONObject staData = words_result.getJSONObject("签发日期");
                JSONObject endData = words_result.getJSONObject("失效日期");
                String startDate = getDate(staData.getString("words"));
                String endDate = endData.getString("words");
                if (!"长期".equals(endDate)) {
                    endDate = getDate(endData.getString("words"));
                }
                jsonObject.put("staData", startDate);
                jsonObject.put("endData", endDate);
            }
            jsonObject.put("imageStatus", status);
            return jsonObject;
        } else {
            if (BaiduImageStatusEnum.REVERSED_SIDE.getCode().equals(status)) {
                msg = BaiduImageStatusEnum.REVERSED_SIDE.getDesc();
            }
            if (BaiduImageStatusEnum.NON_IDCARD.getCode().equals(status)) {
                msg = BaiduImageStatusEnum.NON_IDCARD.getDesc();
            }
            if (BaiduImageStatusEnum.BLURRED.getCode().equals(status)) {
                msg = BaiduImageStatusEnum.BLURRED.getDesc();
            }
            if (BaiduImageStatusEnum.OTHER_TYPE_CARD.getCode().equals(status)) {
                msg = BaiduImageStatusEnum.OTHER_TYPE_CARD.getDesc();
            }
            if (BaiduImageStatusEnum.OVER_EXPOSURE.getCode().equals(status)) {
                msg = BaiduImageStatusEnum.OVER_EXPOSURE.getDesc();
            }
            if (BaiduImageStatusEnum.OVER_DARK.getCode().equals(status)) {
                msg = BaiduImageStatusEnum.OVER_DARK.getDesc();
            }
            if (BaiduImageStatusEnum.UNKNOWN.getCode().equals(status)) {
                msg = BaiduImageStatusEnum.UNKNOWN.getDesc();
            }
            jsonObject.put("msg", msg);
            return jsonObject;
        }
    }

    //获取营业照的有效期
    @Override
    public JSONObject getBusiness(String imgName, String imgUrl) throws IOException {
        JSONObject jsonObject = new JSONObject();
        //获取图片文件
        String imageBase = encodeImgageToBase64(getImgFile(imgName, imgUrl));
        imageBase = imageBase.replaceAll("\r\n", "");
        imageBase = imageBase.replaceAll("\\+", "%2B");//
        String httpUrl = "https://aip.baidubce.com/rest/2.0/ocr/v1/business_license?access_token=" + getAuth();
        String httpArg = "detect_direction=true&image=" + imageBase;
        String jsonResult = request(httpUrl, httpArg);
        System.out.println("返回的结果--------->" + jsonResult);
        JSONObject resJson = JSONObject.parseObject(jsonResult);
        JSONObject words_result = resJson.getJSONObject("words_result");
        JSONObject staData = words_result.getJSONObject("成立日期");
        JSONObject endData = words_result.getJSONObject("有效期");
        JSONObject businessName = words_result.getJSONObject("单位名称");
        JSONObject addressJSONObject = words_result.getJSONObject("地址");
        JSONObject socialCreditCodeJSONObject = words_result.getJSONObject("社会信用代码");
        String staDates = staData.getString("words");
        staDates = staDates.replaceAll("年", "-");
        staDates = staDates.replaceAll("月", "-");
        staDates = staDates.replaceAll("日", "");
        String endDates = endData.getString("words");
        endDates = endDates.replaceAll("年", "-");
        endDates = endDates.replaceAll("月", "-");
        endDates = endDates.replaceAll("日", "");
        System.out.println(staDates);
        System.out.println(endData.getString("words"));
        jsonObject.put("staData", staDates);
        jsonObject.put("endData", endDates);
        jsonObject.put("businessName", businessName.getString("words"));
        jsonObject.put("address", addressJSONObject.getString("words"));
        jsonObject.put("bussAuthNum", socialCreditCodeJSONObject.getString("words"));
        return jsonObject;
    }

    @Override
    public JSONObject getBankCard(String bankCard, String bussUrl) throws IOException {
        //获取图片文件
        String imageBase = encodeImgageToBase64(getImgFile(bankCard, bussUrl));
        imageBase = imageBase.replaceAll("\r\n", "");
        imageBase = imageBase.replaceAll("\\+", "%2B");//
        String httpUrl = "https://aip.baidubce.com/rest/2.0/ocr/v1/bankcard?access_token=" + getAuth();
        String httpArg = "detect_direction=true&image=" + imageBase;
        String jsonResult = request(httpUrl, httpArg);
        System.out.println("返回的结果--------->" + jsonResult);
        JSONObject resJson = JSONObject.parseObject(jsonResult);
        JSONObject result = resJson.getJSONObject("result");
        if (result == null) {
            throw new ControllerException("没有识别到银行卡！");
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("bankCardNumber", result.getString("bank_card_number").replaceAll(" ", ""));
        jsonObject.put("validDate", result.getString("valid_date"));
        jsonObject.put("bankCardType", result.getString("bank_card_type"));
        jsonObject.put("bankName", result.getString("bank_name"));

        return jsonObject;
    }


    public static String getDate(String date) {
        StringBuffer sb = new StringBuffer(date);
        sb.insert(6, "-");
        sb.insert(4, "-");
        return sb.toString();
    }

    // 获取服务器的路径图片
    public static File getImgFile(String imgName, String imgUrl) throws IOException {
        UrlResource urlResource = new UrlResource(new URL(imgUrl));
        File files = File.createTempFile(imgName, ".jpg");
        InputStream in = urlResource.getInputStream();
        try {
            int l = -1;
            FileOutputStream fout = new FileOutputStream(files);
            byte[] tmp = new byte[4024];
            while ((l = in.read(tmp)) != -1) {
                fout.write(tmp, 0, l);
                // 注意这里如果用OutputStream.write(buff)的话，图片会失真，大家可以试试
            }
            fout.flush();
            fout.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭低层流。
            in.close();
        }
        return files;
    }
}
